package com.af.security.auth.util.handler;

import com.af.security.auth.phone.PhoneAuthenticationException;
import com.af.security.property.SecurityProperties;
import com.af.service.AfI18nService;
import com.af.service.AfRedirectService;
import com.af.system.util.AfServletUtils;
import com.af.system.api.result.AfResultUtils;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Locale;

/**
 * @author : zhenyun.su
 * @since : 2020/03/25
 * @common : 登录失败后, 自定义返回值
 * 返回值. 1.Result格式Json数据 2.指定页面
 * 失败原因：
 *   1. badCredentials - 密码错误，
 *   2. UsernameNotFound - 账号不存在，
 *   3. AccountExpired - 账号过期，
 *   4. disabled locked， 账号被禁用 或 被锁定
 *   5. AuthenticationCredentialsNotFound - 密码不存在
 *   6. CredentialsExpired - 密码过期
 *   7. SessionAuthentication - 会话相关异常
 */

@Component
public class AfAuthenticationFailureHandler implements AuthenticationFailureHandler {
    private SecurityProperties securityProperties;
    private AfRedirectService redirectService;
    private AfI18nService i18nService;
    public AfAuthenticationFailureHandler(SecurityProperties securityProperties, AfRedirectService redirectService, AfI18nService i18nService) {
        this.securityProperties = securityProperties;
        this.redirectService = redirectService;
        this.i18nService = i18nService;
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        String error = null;
        String msg = e.getMessage();
        if (e instanceof BadCredentialsException) {
            error = "alert.security.badCredentials";
        }else if (e instanceof UsernameNotFoundException){
            error= "alert.security.account.not-found";
            error= "alert.security.badCredentials";
        }else if (e instanceof AccountExpiredException){
            error= "alert.security.account.expired";
        }else if (e instanceof DisabledException){
            error= "alert.security.account.disabled";
        }else if (e instanceof LockedException){
            error= "alert.security.account.locked";
        }else if (e instanceof AuthenticationCredentialsNotFoundException){
            error= "alert.security.credentials.not-found";
            error= "alert.security.badCredentials";
        }else if (e instanceof CredentialsExpiredException){
            error= "alert.security.credentials.expired";
        }else if (e instanceof SessionAuthenticationException){
            error= "alert.security.max-session.failure";
        }else if (e instanceof PhoneAuthenticationException){
            error= msg;
        }
        if (!StringUtils.isEmpty(error)){
            Locale locale = AfServletUtils.getRequestLocale(httpServletRequest);
            if ("alert.security.max-session.failure".equals(error)){
                Object[] params = {securityProperties.getSessionMaxCount()};
                msg = i18nService.getI18n(error, params, locale);
            }else {
                msg = i18nService.getI18n(error,null, locale);
            }
        }
        redirectService.redirectJson(httpServletResponse, AfResultUtils.failure(msg, null));
    }
}
